package com.itheima.reggie.web.exception;

import com.itheima.reggie.web.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
 * 全局异常处理器
 *
 * @Author Vsunks.v
 * @Date 2023/2/4 18:08
 * @Blog blog.sunxiaowei.net/996.mba
 * @Description: 全局异常处理器
 */

// @ControllerAdvice  // 标注该类为一个全局异常处理类
// @ResponseBody       // 将响应内容写入响应体
@Slf4j
@RestControllerAdvice(annotations = {Controller.class, RestController.class})   //  =
// @ControllerAdvice +
// @ResponseBody
public class GlobalExceptionHandler {


    /**
     * 编写方法，处理指定类型的异常。异常对象会自动赋值给形参
     *
     * @param e 异常对象
     * @return 响应的结果
     */
    @ExceptionHandler(BusinessException.class)  // 处理业务异常
    public R doBusinessException(BusinessException e) {

        // 记录日志（发送邮件给开发者&运维）
        log.warn("出现了业务异常，异常信息：{}", e.getMessage());
        // 保留打印的堆栈信息
        e.printStackTrace();

        // 响应提示信息给用户
        return R.fail(e.getMessage());
    }


    @ExceptionHandler(BindException.class)
    public R doBindException(BindException e) {

        // 获取提示信息
        String defaultMessage = e.getBindingResult().getAllErrors().get(0).getDefaultMessage();

        // 记录日志
        log.warn("参数不合法，异常信息：{}", defaultMessage);
        // 保留打印的堆栈信息
        e.printStackTrace();

        // 响应提示信息给用户
        return R.fail(defaultMessage);

    }

    /**
     * 编写方法，处理指定未知类型的异常。异常对象会自动赋值给形参
     *
     * @param e 异常对象
     * @return 响应的结果
     */
    @ExceptionHandler(Exception.class)  // 处理业务异常
    public R doException(BusinessException e) {

        // 记录日志（发送邮件给开发者&运维）
        log.warn("出现了未知异常，异常信息：{}", e.getMessage());
        // 保留打印的堆栈信息
        e.printStackTrace();

        // 响应提示信息给用户
        return R.fail(e.getMessage());
    }
}
